package com.ruoyi.coin.utils.oklink;


import cn.hutool.json.JSONUtil;
import com.ruoyi.coin.enums.OklinkChainEnum;
import com.ruoyi.coin.enums.OklinkTranFlagEnum;
import com.ruoyi.coin.model.oklink.*;
import com.ruoyi.common.config.CoinConfig;
import com.ruoyi.common.utils.blade.Func;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;

import java.math.BigDecimal;
import java.util.List;

public class OklinkUtils {

    static String OKLINK_API_URL = "https://www.oklink.com";

    // 获取代币余额
    public static BigDecimal getTokenAmount(OklinkChainEnum chainEnum, String usdAddress, String tokenContractAddress) {
        try {
            if(CoinConfig.getDebug()){
                return BigDecimal.valueOf(-1);
            }
            StringBuffer sb = new StringBuffer();
            sb.append(OKLINK_API_URL);
            sb.append("/api/v5/explorer/address/address-balance-fills").append("?");
            sb.append("chainShortName=").append(chainEnum.getCode()).append("&");
            sb.append("address=").append(usdAddress).append("&");
            sb.append("protocolType=token_20").append("&");
            sb.append("tokenContractAddress=").append(tokenContractAddress);

            String url = sb.toString();


            OkHttpClient client = new OkHttpClient.Builder().build();
            Request request = new Request.Builder()
                    .url(url)
                    .addHeader("Ok-Access-Key", CoinConfig.getOklink_api_key())
                    .build();
            Response response = client.newCall(request).execute();
            String bodyStr = response.body().string();
            OklinkTokenBalanceModel model = JSONUtil.toBean(bodyStr, OklinkTokenBalanceModel.class);
            if(Func.isEmpty(model.getData())){
                return BigDecimal.ZERO;
            }

            OklinkTokenBalanceModel.DataModel dataModel = model.getData().get(0);
            OklinkTokenBalanceModel.TokenModel tokenModel = dataModel.getTokenList().get(0);
            String holdingAmount = tokenModel.getHoldingAmount();
            return new BigDecimal(holdingAmount);

        } catch (Exception e) {
            e.printStackTrace();
        }
        return BigDecimal.ZERO;

    }

    //获取交易状态
    public static OklinkTranFlagEnum getTranFlagByHash(OklinkChainEnum chainEnum, String txId){
        try {
            if(CoinConfig.getDebug()){
                return OklinkTranFlagEnum.SUCCESS;
            }
            Thread.sleep(10000);
            StringBuffer sb = new StringBuffer();
            sb.append(OKLINK_API_URL);
            sb.append("/api/v5/explorer/transaction/transaction-fills").append("?");
            sb.append("chainShortName=").append(chainEnum.getCode()).append("&");
            sb.append("txid=").append(txId);

            String url = sb.toString();


            OkHttpClient client = new OkHttpClient.Builder().build();
            Request request = new Request.Builder()
                    .url(url)
                    .addHeader("Ok-Access-Key", CoinConfig.getOklink_api_key())
                    .build();
            Response response = client.newCall(request).execute();
            String bodyStr = response.body().string();
            OklinkTranFlagModel model = JSONUtil.toBean(bodyStr, OklinkTranFlagModel.class);
            if(Func.isEmpty(model.getData())){
                return null;
            }
            OklinkTranFlagModel.DataModel dataModel = model.getData().get(0);
            String state = dataModel.getState();
            return OklinkTranFlagEnum.getByCode(state);


        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    //获取Token20 授权金额
    public static BigDecimal getToken20ApproveAmount(OklinkChainEnum chainEnum, String usdAddress,String tokenAddress){
        try {
            boolean doFlag=true;
            int pageNo=0;
            do{
                StringBuffer sb = new StringBuffer();
                sb.append(OKLINK_API_URL);
                sb.append("/api/v5/tracker/contractscanner/address-authorized-list").append("?");
                sb.append("chainShortName=").append(chainEnum.getCode()).append("&");
                sb.append("address=").append(usdAddress).append("&");
                sb.append("protocolType=token_20").append("&");
                sb.append("limit=100").append("&");
                sb.append("page=").append(++pageNo);

                String url = sb.toString();
                OkHttpClient client = new OkHttpClient.Builder().build();
                Request request = new Request.Builder()
                        .url(url)
                        .addHeader("Ok-Access-Key", CoinConfig.getOklink_api_key())
                        .build();

                Response response = client.newCall(request).execute();
                String bodyStr = response.body().string();

                OklinkApproveModel model = JSONUtil.toBean(bodyStr, OklinkApproveModel.class);
                if(Func.isEmpty(model.getData())){
                    return BigDecimal.ZERO;
                }
                OklinkApproveModel.DataModel dataModel = model.getData().get(0);
                String page = dataModel.getPage();
                String totalPage = dataModel.getTotalPage();
                if(Func.equals(page,totalPage)){
                    doFlag=false;
                }
                List<OklinkApproveModel.ApprovedModel> authorizedList = dataModel.getAuthorizedList();
                if(Func.isEmpty(authorizedList)){
                    return BigDecimal.ZERO;
                }

                if(authorizedList.size()<100){
                    doFlag=false;
                }
                for(OklinkApproveModel.ApprovedModel approvedModel:authorizedList){
                    String tokenContractAddress = approvedModel.getTokenContractAddress();
                    String approvedAmount = approvedModel.getApprovedAmount();
                    if(Func.equals(approvedAmount,"unlimited")){
                        approvedAmount="-1";
                    }
                    if(Func.equals(tokenContractAddress,tokenAddress)){
                        return new BigDecimal(approvedAmount);
                    }

                }
                return BigDecimal.ZERO;
            }while (doFlag);

        } catch (Exception e) {
            e.printStackTrace();
        }
        return BigDecimal.ZERO;
    }

}
